package com.sdweizan.sdk.bytedance.api;

import com.alibaba.fastjson.TypeReference;
import com.sdweizan.sdk.bytedance.bean.BdBaseRequest;
import com.sdweizan.sdk.bytedance.bean.BdBaseResponse;
import com.sdweizan.sdk.bytedance.error.BdError;
import com.sdweizan.sdk.bytedance.error.BdErrorEnum;
import com.sdweizan.sdk.bytedance.error.BdErrorException;
import com.sdweizan.sdk.bytedance.util.HttpClientGetRequestExecutor;
import com.sdweizan.sdk.bytedance.util.HttpClientPostRequestExecutor;
import com.sdweizan.sdk.bytedance.util.JsonUtils;
import com.sdweizan.sdk.bytedance.util.RequestExecutor;
import java.util.Map;

public interface BdService {

  BdMiniAppService getBdMiniAppService();

  String getAccessToken() throws BdErrorException;

  String getAccessToken(boolean forceRefresh) throws BdErrorException;

  default <T extends BdBaseResponse> T get(
      BdBaseRequest requestBody, TypeReference<T> typeReference) throws BdErrorException {
    T byteDanceResponse =
        execute(
            requestBody.requestUri(),
            JsonUtils.transMap(requestBody),
            new HttpClientGetRequestExecutor<>(typeReference));
    BdErrorEnum byteDanceError = BdErrorEnum.findByCode(byteDanceResponse.getErrNo());
    if (BdErrorEnum.ENUM_SUCCESS != byteDanceError) {
      throw new BdErrorException(new BdError(byteDanceError.getCode(), byteDanceError.getMsg()));
    }
    return byteDanceResponse;
  }

  default <T extends BdBaseResponse> T post(
      BdBaseRequest requestBody, TypeReference<T> typeReference) throws BdErrorException {
    T byteDanceResponse =
        execute(
            requestBody.requestUri(),
            JsonUtils.transMap(requestBody),
            new HttpClientPostRequestExecutor<>(typeReference));
    BdErrorEnum byteDanceError = BdErrorEnum.findByCode(byteDanceResponse.getErrNo());
    if (BdErrorEnum.ENUM_SUCCESS != byteDanceError) {
      throw new BdErrorException(new BdError(byteDanceError.getCode(), byteDanceError.getMsg()));
    }
    return byteDanceResponse;
  }

  <T> T execute(
      String requestUri,
      Map<String, Object> requestBody,
      RequestExecutor<T, Map<String, Object>> executor)
      throws BdErrorException;
}
